<template>
  <div class="max-w-3xl mx-auto bg-white shadow rounded-lg overflow-hidden">
    <div class="px-4 py-5 sm:p-6">
      <h3 class="text-lg leading-6 font-medium text-gray-900">啤酒卡路里计算器</h3>
      <div class="mt-2 max-w-xl text-sm text-gray-500">
        <p>计算啤酒的卡路里含量，基于酒精度数和残糖。</p>
      </div>

      <div class="mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-2">
        <!-- 原始比重 -->
        <div>
          <label for="original-gravity" class="block text-sm font-medium text-gray-700">原始比重</label>
          <div class="mt-1 relative rounded-md shadow-sm">
            <input
              type="number"
              name="original-gravity"
              id="original-gravity"
              v-model="originalGravity"
              step="0.001"
              class="focus:ring-brew-amber focus:border-brew-amber block w-full pr-12 sm:text-sm border-gray-300 rounded-md"
              placeholder="1.048"
              @input="calculateCalories"
            >
            <div class="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
              <span class="text-gray-500 sm:text-sm">SG</span>
            </div>
          </div>
        </div>

        <!-- 最终比重 -->
        <div>
          <label for="final-gravity" class="block text-sm font-medium text-gray-700">最终比重</label>
          <div class="mt-1 relative rounded-md shadow-sm">
            <input
              type="number"
              name="final-gravity"
              id="final-gravity"
              v-model="finalGravity"
              step="0.001"
              class="focus:ring-brew-amber focus:border-brew-amber block w-full pr-12 sm:text-sm border-gray-300 rounded-md"
              placeholder="1.010"
              @input="calculateCalories"
            >
            <div class="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
              <span class="text-gray-500 sm:text-sm">SG</span>
            </div>
          </div>
        </div>

        <!-- 啤酒体积 -->
        <div>
          <label for="beer-volume" class="block text-sm font-medium text-gray-700">啤酒体积</label>
          <div class="mt-1 relative rounded-md shadow-sm">
            <input
              type="number"
              name="beer-volume"
              id="beer-volume"
              v-model="beerVolume"
              step="1"
              class="focus:ring-brew-amber focus:border-brew-amber block w-full pr-12 sm:text-sm border-gray-300 rounded-md"
              placeholder="330"
              @input="calculateCalories"
            >
            <div class="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
              <span class="text-gray-500 sm:text-sm">mL</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 计算结果 -->
      <div class="mt-6">
        <div class="rounded-md bg-blue-50 p-4">
          <div class="flex">
            <div class="flex-shrink-0">
              <BeakerIcon class="h-5 w-5 text-blue-400" aria-hidden="true" />
            </div>
            <div class="ml-3">
              <h3 class="text-sm font-medium text-blue-800">卡路里含量</h3>
              <div class="mt-2 text-sm text-blue-700">
                <div class="space-y-1">
                  <p class="font-medium text-2xl">{{ totalCalories }} 千卡</p>
                  <p>酒精贡献：{{ alcoholCalories }} 千卡</p>
                  <p>残糖贡献：{{ carbohydrateCalories }} 千卡</p>
                  <p class="text-xs mt-2">每100mL含：{{ caloriesPer100ml }} 千卡</p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 计算公式说明 -->
      <div class="mt-6">
        <h4 class="text-sm font-medium text-gray-900">计算方法</h4>
        <div class="mt-2 text-sm text-gray-500 space-y-1">
          <p>酒精热量：7.1 千卡/克酒精</p>
          <p>碳水热量：3.7 千卡/克碳水化合物</p>
          <p>考虑因素：酒精度数、残糖含量</p>
        </div>
      </div>

      <!-- 使用说明 -->
      <div class="mt-6 bg-yellow-50 border-l-4 border-yellow-400 p-4">
        <div class="flex">
          <div class="flex-shrink-0">
            <svg class="h-5 w-5 text-yellow-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
              <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
            </svg>
          </div>
          <div class="ml-3">
            <h3 class="text-sm font-medium text-yellow-800">使用说明</h3>
            <div class="mt-2 text-sm text-yellow-700">
              <ul class="list-disc pl-5 space-y-1">
                <li>输入原始比重 (1.035-1.120)</li>
                <li>输入最终比重 (1.005-1.030)</li>
                <li>输入啤酒体积 (mL)</li>
                <li>系统自动计算卡路里含量</li>
                <li>结果包括酒精和残糖热量</li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { BeakerIcon } from '@heroicons/vue/24/outline'

// 输入参数
const originalGravity = ref('')
const finalGravity = ref('')
const beerVolume = ref('')

// 比重转柏拉图度
function sgToPlato(sg) {
  return (-1 * 616.868) + (1111.14 * sg) - (630.272 * Math.pow(sg, 2)) + (135.997 * Math.pow(sg, 3))
}

// 计算酒精度数 (ABW)
function calculateABW(og, fg) {
  return (og - fg) * 105.194
}

// 计算残糖量 (g/L)
function calculateResidualExtract(fg) {
  return sgToPlato(fg) * 10
}

// 计算酒精热量
function calculateAlcoholCalories(og, fg, volume) {
  const abw = calculateABW(og, fg)
  // 酒精密度约为0.789 g/mL
  const alcoholWeight = abw * volume * 0.789 / 100
  // 每克酒精7.1千卡
  return alcoholWeight * 7.1
}

// 计算碳水化合物热量
function calculateCarbohydrateCalories(fg, volume) {
  const residualExtract = calculateResidualExtract(fg)
  // 每克碳水3.7千卡
  return (residualExtract * volume / 1000) * 3.7
}

// 计算总热量
const totalCalories = computed(() => {
  if (!originalGravity.value || !finalGravity.value || !beerVolume.value) return '0'
  
  const og = parseFloat(originalGravity.value)
  const fg = parseFloat(finalGravity.value)
  const volume = parseFloat(beerVolume.value)
  
  if (isNaN(og) || isNaN(fg) || isNaN(volume)) return '0'
  
  const total = Math.round(alcoholCalories.value + carbohydrateCalories.value)
  return total.toLocaleString('en-US')
})

// 计算酒精热量
const alcoholCalories = computed(() => {
  if (!originalGravity.value || !finalGravity.value || !beerVolume.value) return 0
  
  const og = parseFloat(originalGravity.value)
  const fg = parseFloat(finalGravity.value)
  const volume = parseFloat(beerVolume.value)
  
  if (isNaN(og) || isNaN(fg) || isNaN(volume)) return 0
  
  return Math.round(calculateAlcoholCalories(og, fg, volume))
})

// 计算碳水化合物热量
const carbohydrateCalories = computed(() => {
  if (!finalGravity.value || !beerVolume.value) return 0
  
  const fg = parseFloat(finalGravity.value)
  const volume = parseFloat(beerVolume.value)
  
  if (isNaN(fg) || isNaN(volume)) return 0
  
  return Math.round(calculateCarbohydrateCalories(fg, volume))
})

// 计算每100mL热量
const caloriesPer100ml = computed(() => {
  if (!beerVolume.value || parseFloat(beerVolume.value) <= 0) return '0'
  const total = parseFloat(totalCalories.value.replace(/,/g, ''))
  return Math.round((total * 100) / parseFloat(beerVolume.value))
})

// 计算函数
function calculateCalories() {
  if (!originalGravity.value || !finalGravity.value || !beerVolume.value ||
      isNaN(originalGravity.value) || isNaN(finalGravity.value) || isNaN(beerVolume.value)) {
    return
  }

  const og = parseFloat(originalGravity.value)
  const fg = parseFloat(finalGravity.value)
  const volume = parseFloat(beerVolume.value)

  // 范围验证
  if (og < 1.035 || og > 1.120 || 
      fg < 1.005 || fg > 1.030 ||
      volume <= 0 || volume > 10000) {
    return
  }
}

// 监听输入变化
watch(
  [originalGravity, finalGravity, beerVolume],
  calculateCalories
)
</script>

<style scoped>
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
</style> 